package com.fingard.dsp.bank.directbank.zjtlcb02;


import TLCBYQZL.ForTLCBInterface;
import net.sf.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.MD5Util;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.util.FtpUtil;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 *
 * @date 2018/12/07
 */
public class ZJTLCB02Base extends DirectBase {

    private static TransIDHelper idHelper = new TransIDHelper(100000, 999999);

    /**
     * 格式：229020+yyyyMMddHHmmss+6位数字序号
     * @return
     */
    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return "229020"+Format.DateTime14Format.format(tmpDateNow) + idHelper.getNextIDStr();
    }

    /**
     * 格式：yyyyMMddHHmmssSSS
     * @return
     */
    protected String getThirdSeqNo() {
        Date tmpDateNow = new Date();
        return Format.DateTime17Format.format(tmpDateNow);
    }

    protected void JsonHeader(JSONObject jsonObject, ZJTLCB02Header p_bankHeader) throws Exception{
        jsonObject.put("appID",getBankConfig().getValueAsString("appId"));
        jsonObject.put("seqNO",p_bankHeader.seqNO);
        jsonObject.put("signMethod","MD5");
        jsonObject.put("encryptMethod","AES");
        jsonObject.put("appAccessToken",p_bankHeader.appAccessToken);
        jsonObject.put("sign",p_bankHeader.sign);
    }

    protected String getCharset(){
        return getBankConfig().getCharset("utf-8");
    }

    /**
     * 请求银行报文
     * @param p_reqStr：加密报文
     * @param code：请求码
     * @return
     * @throws Exception
     */
    protected String[] sendToBank(String p_reqStr,String code) throws Exception {
        String[] retStr = new String[]{"", ""};
        WriteBankUrlLogLn( "请求银行的地址"+bankFront.serverURL+code);
        WriteBankLogLn("发送至银行的加密报文："+p_reqStr);
        //发送银行前置
        WebRequest tmpWebRequest = new WebRequest(bankFront.serverURL+code);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        //tmpWebRequest.setRequestProperty("connection", "Close");
        String charsetName = getCharset();
        byte[] tmpToWriteBytes = p_reqStr.getBytes(charsetName);
        retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    /**
     * 验证开发者
     * @return
     * @throws Exception
     */
    protected String checkDeveloper(String seqNo) throws Exception{
        WriteBankLogLn("验证开发者start");
        String developer="";
        String random=Format.Time9Format.format(new Date());
        String appSecretKey=bankFront.keyID;
        String sign= MD5Util.md5_(new StringBuilder(random).append(seqNo).append(appSecretKey).toString());
        JSONObject object=new JSONObject();
        object.put("appID",getBankConfig().getValueAsString("appId"));
        object.put("seqNO",seqNo);
        object.put("random",random);
        object.put("sign",sign);
        //发送请求报文
        String[] bankResult = sendToBank(object.toString(),"approveDev");
        //处理响应报文
        if (bankResult[0].length() == 0) {
            JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ",""));
            if(!"".equals(jsonArray.get("appAccessToken")) && jsonArray.get("appAccessToken")!=null){
                developer=jsonArray.get("appAccessToken").toString();
            }
        }
        if("".equals(developer) || developer==null){
            throw new Exception("获取开发者权限失败");
        }
        WriteBankLogLn("验证开发者end");
        return developer;
    }

    /**
     * 拼接备注+对账码
     * @param p_srcXE
     * @param purpose
     * @return
     * @throws Exception
     */
    protected String getPayCode(XElement p_srcXE,String purpose) throws Exception{
        //拼接请求报文体
        XmlTextWriter xmlTextWriter = new XmlTextWriter();
        XElement body = new XElement("body","");
        body.addChild(new XElement("purpose",purpose));//付款备注
        nodeAnalysis(p_srcXE,body,getCharset());
        xmlTextWriter.writeXElement(body);
        xmlTextWriter.writeEndDocument();
        StringBuilder tmpSbMsg = new StringBuilder();
        XmlTextReader xmlSbReader = loadBankRespXmlReader(xmlTextWriter.toXmlString(),tmpSbMsg);
        String payCode=xmlSbReader.getFirstText("/body/purpose");
        return payCode;
    }

    protected static boolean isActiveRetCode(String retCode) {
        if (retCode != null) {
            if (retCode.equals("000000")) {
                return true;
            }
        }
        return false;
    }

    /**
     * 签名证书
     * @param data 需要签名的原始数据
     * @return
     */
    protected String ukeyData(String data) throws Exception{
        WriteBankLogLn("需要签名的原始数据："+data);
        byte[] sign = new byte[4096];
        int[] signLen = new int[1];
        ForTLCBInterface tnt = new ForTLCBInterface();
        String dn= getBankConfig().getValueAsString("signCert");//泰隆银行提供
        WriteBankLogLn("需要签名的dn："+dn);
        int[] iHashAlg = new int[1];
        iHashAlg[0] = 2;//签名算法 1：MD5 2：SHA1 3：SM3
        String pin=getBankConfig().getValueAsString("pin");
        int ret = tnt.SignData(pin.getBytes(),dn.getBytes(), data.getBytes(), sign, signLen, iHashAlg);
        if (0 == ret){
            String s=new String(sign);
            return s;
        }else{
            WriteBankLogLn("签名证书生成失败，请咨询银行人员");
            throw new Exception("签名证书生成失败");
        }
    }

    protected void generateReceiptCodeFile(String receiptId,String filePath,String acctNo,String ccy,String oriTranDate) throws Exception {
        String path = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "datafile" + File.separator + bankFront.code + File.separator + "cltRefNoFile" + File.separator;
        String filePath2 = path + receiptId + ".txt";
        File batFile = new File(filePath2);
        if (!batFile.getParentFile().exists()) {
            batFile.getParentFile().mkdirs();
        }
        String fileContent = "";
        String newFileContent = receiptId + "|" + filePath + "|" + acctNo + "|" + ccy + "|" + oriTranDate;
        if (!batFile.exists()) {
            batFile.createNewFile();
        } else {
            fileContent = FtpUtil.getTextFromFile(filePath2, getCharset());
            if (fileContent.contains(newFileContent)) {
                return;
            }
        }
        FileOutputStream fos = new FileOutputStream(batFile);
        fos.write(fileContent.concat(newFileContent).getBytes());
        fos.close();
    }

    //上送格式为json格式
    protected  String[] sendToATS(String jsonData) throws Exception{
        String[] retStr = new String[]{"",""};
        WriteBankLogLn("2.提交ATS的地址："+ FGBiz.dspCenter.dspSet.receiptPushServerUrl);

        //发送ATS
        WebRequest tmpRequest = new WebRequest(FGBiz.dspCenter.dspSet.receiptPushServerUrl);
        tmpRequest.setConnectTimeout(60000);
        tmpRequest.setRequestProperty("connection", "Close");
        tmpRequest.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        String charsetName = getCharset();
        WriteBankLogLn("3.推送给ATS的json数据"+jsonData);
        byte[] tmpWriteBytes = jsonData.getBytes(charsetName);
        retStr = tmpRequest.upload(tmpWriteBytes, charsetName);
        WriteBankLogLn("4.返回的数据"+retStr[1]);

        return retStr;
    }

    protected void downFromFtp(String localReceiptPath, FtpSet ftpSet,String fileName)  throws Exception {
        FtpPortClient ftpPtClient = new FtpPortClient(ftpSet);
        //从FTP下载回单
        FtpReceiver ftpReceiver = null;
        try {
            ftpPtClient.setLocalPassiveMode();
            ftpPtClient.connect();
            ftpPtClient.list(ftpSet.downDir, false);
            WriteBankLogLn("开始从【" + ftpSet.serverIP + ":" + ftpSet.port + ftpSet.downDir + "】下载回单文件");
            if (ftpPtClient.arFiles.size() > 0) {
                for (String receiptZip : ftpPtClient.arFiles) {
                    if(receiptZip.contains(fileName)){
                        ftpReceiver = ftpPtClient.downloadFile(receiptZip, localReceiptPath + File.separator + receiptZip.substring(receiptZip.lastIndexOf("/") + 1));
                        if (ftpReceiver.isCompleted) {
                            WriteBankLogLn("成功下载回单文件:" + receiptZip+"至"+localReceiptPath);
                            //下载成功后删除ftp文件
                            ftpReceiver = ftpPtClient.deleteFile(receiptZip);
                            if (ftpReceiver.isCompleted) {
                                WriteBankLogLn("成功删除FTP端回单文件:" + receiptZip);
                            } else {
                                WriteBankLogLn(receiptZip + "回单文件删除失败:" + ftpReceiver.connMsg + "+" + ftpReceiver.connState);
                            }
                        } else {
                            WriteBankLogLn(receiptZip + "回单文件下载失败:" + ftpReceiver.connMsg + "+" + ftpReceiver.connState);
                        }
                    }else {
                        WriteBankLogLn("文件"+receiptZip+"还未上传");
                    }
                }
            } else {
                WriteBankLogLn("【" + ftpSet.serverIP + ":" + ftpSet.port + ftpSet.downDir + "】不存在文件");
            }
        } finally {
            ftpPtClient.disconnect();
        }

    }

    public static void main(String[] args) {
        System.loadLibrary("TLCBYQZL");
    }
}
